package com.txc.cloud.auth.common.filter;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.txc.common.global.model.LoginUser;
import com.txc.common.global.model.SysRole;
import com.txc.common.utils.format.ObjectFormat;
import com.txc.common.utils.jwt.TokenManager;
import com.txc.common.utils.middleware.RedisUtils;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

import static com.txc.common.global.constant.StrConstant.AUTHORIZATION;

/**
 * 权限拦截器
 *
 * @ClassName: AuthorityFilter
 * @Author: TXC
 * @Date: 2022-07-30 21:50
 **/
@Component
public class AuthorityFilter extends OncePerRequestFilter {
    @Resource
    private RedisUtils redisUtils;
    @Resource
    private TokenManager tokenManager;

    /**
     * 权限操作
     *
     * @param request  请求
     * @param response 响应
     * @param chain    过滤器链
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        // 获取token
        String token = request.getHeader(AUTHORIZATION);
        // 解析token
        if (StrUtil.isNotBlank(token)) {
            String userId = tokenManager.getUserId(token);
            // 获取表单提供的数据
            LoginUser loginUser = ObjectFormat.objToObject(redisUtils.get(tokenManager.getCacheKey() + userId),
                    LoginUser.class);
            List<String> roles = new ArrayList<>();
            if (ObjectUtil.isNotNull(loginUser)) {
                roles = loginUser.getRoles().stream().map(SysRole::getCode).collect(Collectors.toList());
            }
            Collection<GrantedAuthority> authorities = new ArrayList<>();
            if (ObjectUtil.isNotNull(roles)) {
                roles.stream().filter(StrUtil::isNotBlank).forEach(permission -> authorities.add(new SimpleGrantedAuthority(permission)));
            }
            String username = tokenManager.getUsername(token);
            UsernamePasswordAuthenticationToken authenticationToken =
                    new UsernamePasswordAuthenticationToken(username, token, authorities);
            authenticationToken.setDetails(loginUser);
            // 权限信息设置到权限上下文
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        }
        // 生成信息对象
        chain.doFilter(request, response);
    }
}
